package com.jlnk.androidfmc.model;

import android.app.Application;
import android.os.Handler;
import android.os.Looper;
import androidx.annotation.NonNull;
import androidx.lifecycle.AndroidViewModel;
import androidx.lifecycle.LiveData;
import androidx.lifecycle.MutableLiveData;

import com.jlnk.androidfmc.dao.AddressDao;
import com.jlnk.androidfmc.entity.Address;

import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;

public class AddressVM extends AndroidViewModel {

  private final AddressDao addressDao;
  private final MutableLiveData<List<Address>> _addresses = new MutableLiveData<>();
  private final ExecutorService executorService;
  private Future<?> futureTask;

  public AddressVM(@NonNull Application application) {
    super(application);
    addressDao = new AddressDao(application);
    executorService = Executors.newFixedThreadPool(1);
  }

  public LiveData<List<Address>> getAddresses() {
    return _addresses;
  }

  public List<Address> queryAll() {
    return addressDao.queryAll();
  }

  public void fetchAddresses() {
    futureTask = executorService.submit(() -> {
      List<Address> addresses = addressDao.queryAll();
      _addresses.postValue(addresses);
    });
  }

  public void getAddressById(int id, OnResultCallback<Address> callback) {
    futureTask = executorService.submit(() -> {
      List<Address> addresses = addressDao.queryAll();
      Address address = null;
      for (Address item : addresses) {
        if (item.getId() == id) {
          address = item;
          break;
        }
      }
      Address finalAddress = address;
      new Handler(Looper.getMainLooper()).post(() -> {
        callback.onResult(finalAddress);
      });
    });
  }

  public void insert(Address address) {
    futureTask = executorService.submit(() -> {
      addressDao.insert(address);
      fetchAddresses();
    });
  }

  public void delById(int id) {
    futureTask = executorService.submit(() -> {
      addressDao.delById(id);
      fetchAddresses();
    });
  }

  public void update(Address address, boolean isDefault) {
    futureTask = executorService.submit(() -> {
      addressDao.update(address, isDefault);
      fetchAddresses();
    });
  }

  public interface OnResultCallback<T> {

    void onResult(T result);
  }
}
